<template>
  <div class="app-wrapper">
    <sidebar ref="sidebarChild" class="table-sidebar-container" :tree-data="treeData1" @hideBtn="hideBtn" @getTable="getTable" />
    <div :class="{ 'app-row-close': !sidebar1.opened }" class="app-row">
      <ButtonGroup style="min-width:625px" :btn-show="btnShow" :btn-data="btnData" @BtnClick="BtnClick" />
      <InlineEditTable ref="child" :depart-ment="departMent" :table-height="tableHeight" :table-btn-data="tableBtnData" @rowClick="rowClick" />
      <el-dialog :visible.sync="dialogBtnVisible" class="btn" width="900px" top="2vh">
        <div slot="title" style="padding-bottom:0;">
          <div style="margin:0;font-size:18px;">角色用户</div>
        </div>
        <RoleSidebar ref="roleSidebarChild" class="table-sidebar-container" :tree-data="treeData" :multiple="false" style="height:420px;" @selectBtnList="selectBtnList" />
        <div class="btn-group">
          <h3 style="margin:5px 0 0 0;width:200px">当前角色：<span v-if="rowData">{{ rowData.roleName }}</span></h3>
          <el-input v-model="depInput" style="width:200px;" placeholder="请输入内容" size="mini" />
          <el-button style="transform: translateX(80px);" type="primary" size="mini" @click="selectAll">全选</el-button>
          <div v-loading="listLoading" style="height:92%;width:100%;">
            <vue-scroll style="height:100%">
              <el-button v-for="item in DeptUsers" :key="item.userName" :type="item.type" size="mini" class="six" @click="checkedBtn(item)"><font-awesome-icon :icon="item.icon" size="lg" fixed-width />{{ item.userName }}<font-awesome-icon v-if="item.select" class="iconcheck" :icon="['fas','check']" fixed-width /></el-button>
            </vue-scroll>
          </div>
        </div>
        <div slot="footer" class="dialog-footer">
          <el-button @click="dialogBtnVisible = false">
            取消
          </el-button>
          <el-button type="primary" @click="EditModuleBtnList">
            确认
          </el-button>
        </div>
      </el-dialog>

      <el-dialog :visible.sync="dialogRoleVisible" class="btn" width="900px" top="2vh">
        <div slot="title">
          <div style="margin:0;font-size:18px;">角色权限</div>
          <div class="tips">
            <font-awesome-icon :icon="['far', 'lightbulb']" fixed-width /><span>温馨提示：点击模块中的多选框，可以同时保存多个模块的按钮配置,而且保存时，至少要选中一个</span>
          </div>
        </div>
        <RoleSidebar ref="adminSidebarChild" class="table-sidebar-container" :tree-data="treeData2" :multiple="true" style="height:420px;" @selectBtnList="selectAdminBtnList" />
        <div class="btn-group">
          <h3 style="margin:0 0 3px 0;width:300px">当前模块：{{ moduleName }}</h3><el-button style="transform: translateX(190px);" type="primary" size="mini">全选</el-button>
          <div v-if="btnList.list.length>0" class="btn-group-content">
            <el-button v-for="btnItem in btnList.list" :key="btnItem.id" :type="btnItem.backColor | btnFilter" size="small" @click="checkedAdmin(btnItem)"><font-awesome-icon v-if="btnItem.iCon" :icon="btnItem.iCon | btnIconFilter" fixed-width />{{ btnItem.btnName }}<font-awesome-icon v-if="btnItem.select" class="iconcheck" :icon="['fas','check']" fixed-width /></el-button>
          </div>
        </div>
        <div slot="footer" class="dialog-footer">
          <el-button @click="dialogRoleVisible = false">
            取消
          </el-button>
          <el-button type="primary" @click="AdminEditModuleBtnRole">
            确认
          </el-button>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import Sidebar from '@/components/Sidebar'
import ButtonGroup from '@/components/ButtonGroup'
import InlineEditTable from './components/InlineEditTable'
import RoleSidebar from './components/Sidebar'
import { GetDepts, GetUserModuleBtns, GetRoleUsers, GetDeptUsers, Module_GetModuleBtns, GetModuleBtnRole, GetModule, EditRoleUsers, EditModuleBtnRole, btnMap, IconFilter } from '@/api/system'
import { setTimeout } from 'timers'
import { mapState, mapGetters } from 'vuex'
import * as R from 'ramda'

/* eslint-disable */
function filterLeft(lists) {
  const res = []
  lists.forEach(list => {
    const tmp = { ...list }
    tmp.title = list.deptContent || list.moduleName || ''
    tmp.expanded = false
    tmp.type = 1
    if (tmp.deptID === 3 || tmp.deptID === 1041) {
      tmp.expanded = true
    }
    if (tmp.child && tmp.child.length > 0) {
      tmp.children = filterLeft(tmp.child)
    }
    res.push(tmp)
  })
  return res
}

function filterLeftRole(lists) {
  const res = []
  lists.forEach(list => {
    const tmp = { ...list }
    tmp.title = list.deptContent || ''
    tmp.expanded = false
    tmp.type = 1
    if (tmp.child && tmp.child.length > 0) {
      tmp.children = filterLeftRole(tmp.child)
    }
    res.push(tmp)
  })
  return res
}

function filterAdmin(lists, btnGroup) {
  const res = []
  lists.forEach(list => {
    const tmp = { ...list }
    tmp.title = list.deptContent || list.moduleName || ''
    tmp.expanded = false
    tmp.type = 1
    if (tmp.deptID === 3 || tmp.deptID === 1041 || tmp.title === 'nm') {
      tmp.expanded = true
    }
    btnGroup.forEach(n => {
      tmp.checked = false
      if (n.id === tmp.id) {
        tmp.checked = true
      }
    })
    if ((tmp.child && tmp.child.length > 0) || tmp.title === 'nm') {
      tmp.children = filterAdmin(tmp.child, btnGroup)
    }
    res.push(tmp)
  })
  return res
}
export default {
  name: 'Role',
  components: {
    Sidebar,
    RoleSidebar,
    ButtonGroup,
    InlineEditTable
  },
  filters: {
    btnFilter(type) {
      return btnMap[type]
    },
    btnIconFilter(icon) {
      return IconFilter(icon)
    }
  },
  data() {
    return {
      tableHeight: 500,
      departMent: 'KM集团',
      node: {},
      rowData: null,
      btnShow: true,
      treeResponse: null,
      treeData2: [{
        title: 'node1',
        expanded: true,
        children: []
      }],
      treeData1: [{
        title: 'node1',
        expanded: true,
        children: []
      }],
      treeData: [{
        title: 'node1',
        expanded: true,
        children: []
      }],
      btnData: [],
      tableBtnData: [],
      RoleUsers: [],
      DeptUsers: [],
      deptNode: null,
      depInput: null,
      moduleName: '',
      AdimnUsers: [],
      AdimnDeptUsers: [],
      btnList: {
        id: 0,
        list: []
      },
      listLoading: false,
      depSelectAll: false,
      dialogBtnVisible: false,
      dialogRoleVisible: false
    }
  },
  computed: {
    ...mapState({
      sidebar1: state => state.app.sidebar
    }),
    ...mapGetters([
      'roles',
      'userID'
    ])
  },
  mounted() {
    setTimeout(() => {
      this.setTableHeight()
    }, 100)
    window.addEventListener('resize', this.setTableHeight)
    this.getTreeData()
    GetUserModuleBtns({ moduleId: this.$route.meta.id, userId: this.userID }).then(response => {
      const data = response.data
      const isEven = n => n.btnName === '修改' || n.btnName === '删除' || n.btnName === '查看'
      const isNoEven = n => n.btnName !== '修改' && n.btnName !== '删除' && n.btnName !== '查看'
      const isDisable = n => n.name === '角色用户' || n.name === '角色权限' ? n.disabled = true : n.disabled = false
      const btnItem = x => { return { type: btnMap[x.backColor], name: x.btnName, icon: IconFilter(x.iCon) } }
      this.btnData = R.compose(R.forEach(isDisable), R.map(btnItem), R.filter(isNoEven))(data)
      this.tableBtnData = R.compose(R.map(btnItem), R.filter(isEven))(data)
    })
  },
  watch: {
    depInput: function (d) {
      this.selectBtnList(this.deptNode)
    }
  },
  methods: {
    EditModuleBtnList() {
      EditRoleUsers(this.RoleUsers).then(response => {
        this.$message({
          message: '操作成功',
          type: 'success'
        })
      })
    },
    setTableHeight() {
      this.tableHeight = document.querySelector('.app-row').offsetHeight - 150
    },
    getTable(node) {
      this.node = node
      this.departMent = this.node.title
      this.$refs.child.getList(this.node.deptID)
      const isDisable = n => n.name === '角色用户' || n.name === '角色权限' ? n.disabled = true : n.disabled = false
      this.btnData.forEach(isDisable)
    },
    hideBtn() {
      this.btnShow = false
    },
    rowClick(rowData) {
      const isDisable = n => n.disabled = false
      this.btnData.forEach(isDisable)
      this.rowData = rowData
    },
    BtnClick(name) {
      if (name === '新增') {
        this.$refs.child.handleCreate(this.node.id)
      }
      if (name === '刷新') {
        this.$refs.child.getList(this.node.deptID)
      }
      if (name === '角色用户') {
        this.dialogBtnVisible = true
        this.getRoleTree()
        this.getDeptUsersAll()
      }
      if (name === '角色权限') {
        this.dialogRoleVisible = true
        this.btnList = {
          id: 0,
          list: []
        }
        this.getAdminTree()
        this.getDeptAdminAll()
      }
    },
    async getDeptUsersAll() {
      this.listLoading = true
      const RoleUsers = await GetRoleUsers(this.rowData.id)
      const DeptUsers = await GetDeptUsers(1)
      this.RoleUsers = RoleUsers.data ? RoleUsers.data : []
      this.DeptUsers = DeptUsers.data ? DeptUsers.data : []
      this.DeptUsersForEach()
      this.listLoading = false
    },
    selectBtnList(node, title) {
      if (node) {
        GetDeptUsers(node.deptID).then(res => {
          this.DeptUsers = res.data
          this.deptNode = node
          this.DeptUsersForEach()
        })
      }
    },
    DeptUsersForEach() {
      this.depSelectAll = false
      if (this.depInput) {
        const filterDep = n => n.userName.indexOf(this.depInput) !== -1
        this.DeptUsers = this.DeptUsers.filter(filterDep)
      }
      this.DeptUsers.forEach(res => {
        if (res.sex) {
          res.type = 'primary'
          res.icon = ['fa', 'mars']
        } else {
          res.type = 'danger'
          res.icon = ['fa', 'venus']
        }
        res.select = false
        if (this.RoleUsers.length > 0) {
          this.RoleUsers.forEach(n => {
            if (n.userID === res.userID) {
              res.select = true
            }
          })
        }
      })
    },
    selectAll() {
      this.depSelectAll = !this.depSelectAll
      this.DeptUsers = this.DeptUsers.map(res => {
        res.select = this.depSelectAll
        return res
      })
      const pushRole = this.DeptUsers.map(res => {
        return { id: 0, roleID: this.rowData.id, userID: res.userID }
      })
      if (this.depSelectAll) {
        this.RoleUsers = [...this.RoleUsers, ...pushRole]
      } else {
        pushRole.forEach(res => {
          const roleFilter = n => n.userID !== res.userID
          this.RoleUsers = this.RoleUsers.filter(roleFilter)
        })
      }
    },
    checkedBtn(node) {
      let saveSelect = null
      this.DeptUsers = this.DeptUsers.map(n => {
        if (n.userID === node.userID) {
          n.select = !n.select
          saveSelect = n.select
        }
        return n
      })
      if (saveSelect) {
        const roleObjs = { id: 0, roleID: this.rowData.id, userID: node.userID }
        const has = this.RoleUsers.some(res => res.userID === roleObjs.userID)
        if (!has) {
          this.RoleUsers.push(roleObjs)
        }
      } else {
        const userFilter = n => n.userID !== node.userID
        this.RoleUsers = this.RoleUsers.filter(userFilter)
      }
    },
    getTreeData() {
      GetDepts()
        .then(response => {
          this.treeResponse = response.data
          const resData = [
            {
              title: response.data.deptContent,
              deptCode: response.data.deptCode,
              deptID: response.data.deptID,
              expanded: true,
              type: 1,
              children: filterLeft(response.data.child)
            }
          ]
          this.treeData1 = resData
        })
    },
    getRoleTree() {
      const resDataTree = [
        {
          title: this.treeResponse.deptContent,
          deptCode: this.treeResponse.deptCode,
          deptID: this.treeResponse.deptID,
          expanded: true,
          type: 1,
          children: filterLeftRole(this.treeResponse.child)
        }
      ]
      this.treeData = resDataTree
    },
    getAdminTree() {
      GetModule().then(response => {
        const resDataTree = [
          {
            title: 'nm',
            moduleName: 'nm',
            id: 1,
            type: 1,
            expanded: true,
            child: filterLeft(response.data),
            children: filterLeft(response.data)
          }
        ]
        this.treeData2 = resDataTree
      })
    },
    selectAdminBtnList(node, title) {
      if (node) {
        this.moduleName = node.title
        const checkes = this.AdimnUsers.filter(n => n.moduleID === node.id)
        const push = n => {
          if (n.id === node.id) {
            this.btnList = {
              id: node.id,
              list: n.list
            }
          }
        }
        this.AdimnDeptUsers.forEach(push)
        if (this.btnList.list.length > 0) {
          this.btnList.list.forEach(n => {
            n.select = false
            checkes.forEach(c => {
              if (c.btnID === n.id) {
                n.select = true
              }
            })
          })
        }
      }
    },
    async getDeptAdminAll() {
      this.listLoading = true
      const AdimnUsers = await GetModuleBtnRole(this.rowData.id)
      const AdimnDeptUsers = await Module_GetModuleBtns()
      this.AdimnUsers = AdimnUsers.data ? AdimnUsers.data : []
      this.AdimnDeptUsers = AdimnDeptUsers.data ? AdimnDeptUsers.data : []
      this.treeData2 = filterAdmin(this.treeData2, this.AdimnDeptUsers)
      this.listLoading = false
    },
    checkedAdmin(btnItem) {
      this.btnList.list = this.btnList.list.map(n => {
        if (btnItem.id === n.id) {
          n.select = !n.select
        }
        return n
      })
      const btnCheckedItem = {
        "id": 0,
        "moduleID": this.btnList.id,
        "roleID": this.rowData.id,
        "btnID": btnItem.id
      }
      const hasBtn = this.AdimnUsers.some(n => n.moduleID === btnCheckedItem.moduleID && n.btnID === btnCheckedItem.btnID)
      if (btnItem.select && !hasBtn) {
        this.AdimnUsers.push(btnCheckedItem)
      }
      if (!btnItem.select && hasBtn) {
        const check = n => n.moduleID === btnCheckedItem.moduleID && n.btnID === btnCheckedItem.btnID
        const index = this.AdimnUsers.findIndex(check)
        this.AdimnUsers.splice(index, 1)
      }
    },
    AdminEditModuleBtnRole() {
      EditModuleBtnRole(this.AdimnUsers).then(res => {
        this.$message({
          message: '操作成功',
          type: 'success'
        })
      })
    }
  }
}
</script>

<style lang="scss" scoped>
@import "~@/styles/mixin.scss";
@import "~@/styles/variables.scss";

.app-wrapper {
  @include clearfix;
  position: relative;
  height: 100%;
  width: 100%;
  display: flex;
  .table-sidebar-container {
    transition: width 0.28s;
    width: 300px !important;
    height: 100%;
    z-index: 1001;
    border-right: solid 1px #e6e6e6;
    overflow: hidden;
  }
  .app-row {
    width: calc(100vw - 510px);
    height: calc(100vh - 100px);
    padding: 10px;
    overflow: hidden;
  }
  .app-row-close {
    width: calc(100vw - 350px);
  }
}
.right-main-container {
  min-height: 100%;
  transition: margin-left 0.28s;
  position: relative;
}
.table-right-container {
  padding: 10px;
}
</style>

<style>
.tips {
  padding: 5px;
  border-bottom: 1px solid #e5e5e5;
  background: #fffdcd;
  color: #bc7b21;
  font-size: 14px;
}
.el-dialog__body {
  padding-top: 10px;
}
.btn .el-dialog__body {
  display: flex;
  padding-top: 0;
  padding-bottom: 5px;
}
.btn .el-dialog__body .table-sidebar-container {
  border-bottom: 1px dotted #ccccdd;
}
.btn .btn-group {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  width: calc(100% - 300px);
  height: 420px;
  z-index: 1001;
  border: solid 1px #e6e6e6;
  margin: 0;
  border-left: 0;
  padding-top: 10px;
  padding-left: 5px;
}
.btn .btn-group button {
  margin: 0 5px 5px 0;
  position: relative;
}
.btn .btn-group .btn-group-content {
  width: 100%;
  height: 92%;
}
.iconcheck {
  position: absolute;
  right: 0;
  bottom: 0px;
}
.halo-tree .tree-node-el {
  background-color: rgba(0, 0, 0, 0);
}
.six {
  margin: 0 5px 5px 10px;
  min-width: 120px;
}
</style>
